<template>
  <div class="third-comp">
    <div class="left">
      <el-card>
        <template #header>
          <div class="css-2">关键词搜索</div>
        </template>
        <template #default>
          <div class="main">
            <div class="charts">
              <div class="left-chart">
                <div class="title">搜索用户量</div>
                <div class="number mt-10">{{ userNum }}</div>
                <v-chart :option="userOption"></v-chart>
              </div>
              <div class="right-chart">
                <div class="title">搜索量</div>
                <div class="number mt-10">{{ searchNum }}</div>
                <v-chart :option="searchOption"></v-chart>
              </div>
            </div>
            <div class="table">
              <el-table :data="pageData">
                <el-table-column label="排名" prop="rank"></el-table-column>
                <el-table-column label="关键词" prop="keyWord"></el-table-column>
                <el-table-column label="总搜索量" prop="totalSearch"></el-table-column>
                <el-table-column label="搜索用户数" prop="totalUser"></el-table-column>
              </el-table>
              <!-- 
                background: 是否为分页按钮添加背景色
                layout: 组件布局，子组件名用逗号分隔
                prev (上一页按钮), next (下一页按钮), pager (分页列表),
                total:总条目数(即所有数据的总数),default-page-size:每页默认的条目个数(即每页默认显示的数据记录)，不设置时默认为10
                page-size: 每页显示条目个数(即每页显示的数据记录)
                总页数=total/page-size,向上取整,比如这里总条目数是20,每页显示条目个数是6,那么总页数为4,即total/page-size=4,向上取整为4
                @current-change:在这个Element-plus的自定义事件中可以将当前页码传递给事件处理函数
              -->
              <el-pagination
                background
                layout="prev,pager,next"
                :page-size="pageSize"
                :total="tableData.length"
                @current-change="handleCurrentChange"></el-pagination>
            </div>
          </div>
        </template>
      </el-card>
    </div>
    <div class="right">
      <el-card shadow="hover">
        <template #header>
          <div class="css-2">分类销售排行</div>
          <!-- 单选组 -->
          <el-radio-group v-model="type" @change="handleChange">
            <el-radio-button label="品类" value="category"></el-radio-button>
            <el-radio-button label="商品" value="product"></el-radio-button>
          </el-radio-group>
        </template>
        <template #default>
          <v-chart :option="categoryOption"></v-chart>
        </template>
      </el-card>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';

import { getKeyWordsData, getCategoryData } from '@/api/index.js';

const tableData = ref([]);
const categoryData = ref({});
// 当前页码,默认为1
const page = ref(1);
// 每页显示条目个数,默认为6
const pageSize = ref(6);

// 用户量图表配置
const userOption = ref({});
// 搜索量图表配置
const searchOption = ref({});
// 分类搜索图表配置
const categoryOption = ref({});
// 热门搜索类型
const type = ref('category');

// 使用计算属性,根据当前页码和每页显示条目个数,计算当前页要显示的数据
const pageData = computed(() => {
  const start = (page.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  return tableData.value.slice(start, end);
});

// 总用户量
const userNum = computed(() => {
  return tableData.value.reduce((acc, cur) => {
    return acc + cur.totalUser;
  }, 0);
});

// 总搜索量
const searchNum = computed(() => {
  return tableData.value.reduce((acc, cur) => {
    return acc + cur.totalSearch;
  }, 0);
});

// vulue:形参,指的是当前页码
const handleCurrentChange = value => {
  page.value = value;
};

// 封装option
const renderLineChart = (chartOption, data) => {
  chartOption.value = {
    xAxis: {
      type: 'category',
      show: false,
      boundaryGap: false,
    },
    yAxis: {
      type: 'value',
      show: false,
    },
    grid: {
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
    },
    series: [
      {
        type: 'line',
        data: data,
        areaStyle: {
          color: 'skyblue',
        },
        itemStyle: {
          opacity: 0,
        },
        smooth: true,
      },
    ],
  };
};

const renderCategoryChart = data => {
  // legend要求series的data数组中对象必须有name属性,
  const _data = data.map(item => {
    return {
      // title: item.title,
      // value: item.value,
      // 或者使用展开运算符如下
      ...item,
      // 添加一个name属性
      name: `${item.title} | ${item.value}`,
    };
  });

  const total = data.reduce((acc, cur) => {
    return acc + cur.value;
  }, 0);

  categoryOption.value = {
    title: [
      {
        text: '品类分布',
        textStyle: {
          fontSize: 14,
          color: '#666',
        },
      },
      {
        text: '累计订单量',
        subtext: total,
        textAlign: 'center',
        x: '40%',
        y: '45%',
        textStyle: {
          fontSize: 14,
          color: '#999',
        },
        subtextStyle: {
          fontSize: 28,
          color: '#333',
        },
      },
    ],
    tooltip: {
      /* 
        formatter 是 tooltip 配置中的一个函数，
        它接收一个参数 params，这个参数包含了当前鼠标悬停位置的详细信息
        比如系列名称（seriesName）、数据标记（marker）、数据标题（data.title）和数据值（data.value）等
      */
      formatter(params) {
        // console.log(params);
        // seriesName要求series中必须有name属性
        const res = `
          ${params.seriesName}<br>
          ${params.marker} ${params.data.title} <br>
          ${params.marker} 销售额: ${params.data.value} <br>
        `;
        return res;
      },
    },
    legend: {
      top: 'top',
      left: '80%',
      //orient:图例列表的布局朝向,可选值有'horizontal'(水平)和'vertical'(垂直)
      orient: 'vertical',
      textStyle: {
        color: '#888',
      },
    },
    series: [
      {
        name: '品类分布',
        type: 'pie',
        radius: ['45%', '60%'], // 饼图的半径[内半径，外半径]
        center: ['40%', '50%'], // 饼图的中心坐标
        itemStyle: {
          // borderWidth: 图形边框线宽,单位px，默认为0（无边框）
          borderWidth: 10,
          borderColor: '#fff',
        },
        label: {
          //position:标签的位置,可选值有'outside'(外部)、'inside'(内部)、'center'(内部)
          position: 'outside',
          // formatter:标签内容格式器,支持字符串模板和回调函数两种形式
          formatter(params) {
            // console.log(params);
            return params.data.title;
          },
        },
        // data: [
        //   { value: 161, title: '粉面粥店' },
        //   { value: 361, title: '汉堡披萨' },
        //   { value: 344, title: '麻辣烫' },
        //   { value: 287, title: '盖浇饭' },
        //   { value: 189, title: '广式烧腊' },
        // ],
        data: _data,
      },
    ],
  };
};

const handleChange = () => {
  if (type.value === 'category') {
    renderCategoryChart(categoryData.value.data1);
  } else if (type.value == 'product') {
    renderCategoryChart(categoryData.value.data2);
  }
};

onMounted(async () => {
  tableData.value = await getKeyWordsData();
  categoryData.value = await getCategoryData();
  // console.log(tableData.value);
  // 由于接口返回的数据格式不是我们希望, 因此需要对原始数据进行加工处理
  const userData = tableData.value
    .map(item => item.totalUser)
    .slice(0, 10)
    .reverse();
  const searchData = tableData.value
    .map(item => item.totalSearch)
    .slice(0, 10)
    .reverse();

  renderLineChart(userOption, userData);
  renderLineChart(searchOption, searchData);

  renderCategoryChart(categoryData.value.data1);
});
</script>

<style lang="scss" scoped>
.third-comp {
  margin-top: 20px;
  display: flex;
  gap: 20px;
  .left {
    flex: 1;
    .el-card__header {
      padding: 18px 20px;
      border-bottom: 1px solid #ebeef5;
    }
    .css-2 {
      font-weight: 600;
    }
    .main {
      padding: 20px;
    }
    .charts {
      display: flex;
      gap: 20px;
      .left-chart,
      .right-chart {
        flex: 1;
        .title {
          font-size: 14px;
          color: #727171;
        }
        .number {
          font-size: 20px;
          font-weight: 600;
        }
        .mt-10 {
          margin-top: 10px;
        }
        // v-chart设置的默认样式,自带类名
        .echarts {
          height: 50px;
        }
      }
    }
    .table {
      .el-pagination {
        margin-top: 16px;
        display: flex;
        justify-content: flex-end;
      }
    }
  }
  .right {
    flex: 1;
    .el-card {
      height: 100%;
      :deep(.el-card__header) {
        position: relative;
        padding: 18px 20px;
        border-bottom: 1px solid #ebeef5;
        .css-2 {
          font-weight: 600;
        }
        .el-radio-group {
          position: absolute;
          // right: 2%;
          // top: 10%;
          top: 10px;
          right: 20px;
        }
      }
      :deep(.el-card__body) {
        padding: 37px;
        height: 500.1px;
        .pie-chart {
          height: 100%;
        }
      }
    }
  }
}
</style>
